package cn.iocoder.yudao.module.product.service.report;

import cn.iocoder.yudao.module.infra.api.file.FileApi;
import cn.iocoder.yudao.module.product.controller.admin.emissionsource.vo.EmissionSourceDownloadVO;
import cn.iocoder.yudao.module.product.controller.admin.report.vo.*;
import cn.iocoder.yudao.module.product.convert.emissionsource.EmissionSourceConvert;
import cn.iocoder.yudao.module.product.dal.dataobject.calculation.CalculationDO;
import cn.iocoder.yudao.module.product.dal.dataobject.calculation.EmissionCalculationDO;
import cn.iocoder.yudao.module.product.dal.dataobject.calculationmodel.CalculationModelDO;
import cn.iocoder.yudao.module.product.dal.dataobject.calculationmodel.ProcessModelDO;
import cn.iocoder.yudao.module.product.dal.dataobject.emissionsource.EmissionSourceDO;
import cn.iocoder.yudao.module.product.dal.dataobject.process.EmissionProcessDO;
import cn.iocoder.yudao.module.product.dal.dataobject.process.ProcessDO;
import cn.iocoder.yudao.module.product.dal.dataobject.productmanagement.ProductManagementDO;
import cn.iocoder.yudao.module.product.dal.dataobject.report.ReportDO;
import cn.iocoder.yudao.module.product.dal.mysql.calculation.EmissionCalculationMapper;
import cn.iocoder.yudao.module.product.dal.mysql.calculationmodel.CalculationModelMapper;
import cn.iocoder.yudao.module.product.dal.mysql.calculationmodel.ProcessModelMapper;
import cn.iocoder.yudao.module.product.dal.mysql.emissionsource.EmissionSourceMapper;
import cn.iocoder.yudao.module.product.dal.mysql.process.EmissionProcessMapper;
import cn.iocoder.yudao.module.product.dal.mysql.process.ProcessMapper;
import cn.iocoder.yudao.module.product.dal.mysql.productmanagement.ProductManagementMapper;
import cn.iocoder.yudao.module.product.dal.mysql.report.ReportMapper;
import cn.iocoder.yudao.module.product.service.calculation.CalculationService;
import cn.iocoder.yudao.module.product.util.TranslateUtil;
import cn.iocoder.yudao.module.product.util.WordUtils;
import cn.iocoder.yudao.module.system.api.tenant.TenantApi;
import cn.iocoder.yudao.module.system.api.tenant.dto.TenantRespDTO;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import javax.validation.Valid;

import org.springframework.validation.annotation.Validated;


import cn.iocoder.yudao.module.product.dal.dataobject.report.ReportDownloadDO;
import cn.iocoder.yudao.module.product.convert.report.ReportDownloadConvert;
import cn.iocoder.yudao.module.product.dal.mysql.report.ReportDownloadMapper;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.*;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY;

/**
 * 报告下载 Service 实现类
 *
 * @author wcl
 */
@Service
@Validated
public class ReportDownloadServiceImpl implements ReportDownloadService {

    @Resource
    private ProductManagementMapper productManagementMapper;

    @Resource
    private ReportDownloadMapper reportDownloadMapper;

    @Resource
    private ReportMapper reportMapper;

    @Resource
    private ReportService reportService;

    @Resource
    private CalculationService calculationService;

    @Resource
    private CalculationModelMapper calculationModelMapper;

    @Resource
    private ProcessMapper processMapper;

    @Resource
    private ProcessModelMapper processModelMapper;

    @Resource
    private EmissionSourceMapper emissionSourceMapper;

    @Resource
    private EmissionProcessMapper emissionProcessMapper;

    @Resource
    private EmissionCalculationMapper emissionCalculationMapper;

    @Resource
    private TenantApi tenantApi;

    @Resource
    private FileApi fileApi;

    @Override
    public Long createReportDownload(@Valid ReportDownloadExportReqVO reqVO) {
        // 文件模板
        String templateName = "model";
        // 使用Map存储数据
        HashMap<Object, Object> data = new HashMap<>();
        // 获取报告信息
        ReportDO report = reportService.getReport(reqVO.getReportId());
        // 获取报告时间
        SimpleDateFormat sdf = new SimpleDateFormat(FORMAT_YEAR_MONTH_DAY);
        String reportTime = sdf.format(new Date());
        data.put("reportTime", reportTime);
        System.out.println(reportTime);
        // 获取组织信息
        ReportDO reportDO = reportMapper.selectById(reqVO.getReportId());
        TenantRespDTO tenant = tenantApi.getTenant(reportDO.getTenantId()).getCheckedData();
        String tenantName = tenant.getName();
        data.put("organization", tenantName);
        // 获取产品碳足迹核算信息
        CalculationDO calculationDO = calculationService.getCalculation(reportDO.getCalculationId());
        data.put("calculation", calculationDO);
        // 核算模型信息
        CalculationModelDO calculationModelDO = calculationModelMapper.selectById(calculationDO.getCalculationModelId());
        data.put("calculationModel", calculationModelDO);
        // 产品信息
        ProductManagementDO productManagementDO = productManagementMapper.selectById(calculationModelDO.getProductId());
        data.put("product", productManagementDO);
        String lifecycle = (!calculationModelDO.getLifecycle() ? "从摇篮到大门" : "从摇篮到坟墓");
        data.put("lifecycle", lifecycle);
        // 获得产品碳足迹核算阶段信息
        HashMap<String, Double> periodMap = (!calculationModelDO.getLifecycle() ?
                new HashMap<String, Double>() {{
                    put("原材料获取", 0.0);
                    put("生产制造", 0.0);
                    put("分销", 0.0);
                    put("总量", 0.0);
                }} :
                new HashMap<String, Double>() {{
                    put("原材料获取", 0.0);
                    put("生产制造", 0.0);
                    put("分销", 0.0);
                    put("使用", 0.0);
                    put("废弃", 0.0);
                    put("总量", 0.0);
        }});
        // 创建阶段列表，用于ftl文件
        List<String> periodList = new ArrayList<>();
        periodList.add("原材料获取");
        periodList.add("生产制造");
        periodList.add("分销");
        periodList.add("使用");
        periodList.add("废弃");
        data.put("periodList", periodList);
        // 查找出所有工序模型关联
        QueryWrapper<ProcessModelDO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("model_id", calculationModelDO.getId());
        List<ProcessModelDO> processModelDOList = processModelMapper.selectList(queryWrapper);
        // 嵌套排放源列表
        Integer cycle = (!calculationModelDO.getLifecycle()) ? 3 : 5;
        data.put("cycle", cycle);
        List<List<EmissionSourceDownloadVO>> listsEmissionSource = new ArrayList<>(cycle - 1);
        // 根据生命周期向嵌套列表中添加空子列表
        while (listsEmissionSource.size() <= cycle - 1) {
            listsEmissionSource.add(new ArrayList<>());
        }
        System.out.println();
        // 遍历所有工序
        for (ProcessModelDO processModelDO : processModelDOList) {
            // 查询工序
            ProcessDO processDO = processMapper.selectById(processModelDO.getProcessId());
            // 判断当前工序所属阶段
            String periodName = processModelDO.getPeriodName();
            Integer index =0;
            switch (periodName){
                case "原材料获取":index = 0;break;
                case "生产制造":index = 1;break;
                case "分销":index = 2;break;
                case "使用":index = 3;break;
                case "废弃":index = 4;break;
            }
            // 查询工序的所有排放源
            QueryWrapper<EmissionProcessDO> queryWrapper1 = new QueryWrapper<>();
            queryWrapper1.eq("process_id", processDO.getId());
            List<EmissionProcessDO> emissionProcessDOList = emissionProcessMapper.selectList(queryWrapper1);
            // 遍历该工序的所有排放源
            for (EmissionProcessDO emissionProcessDO : emissionProcessDOList) {
                // 查询排放源基本信息
                EmissionSourceDO emissionSourceDO = emissionSourceMapper.selectById(emissionProcessDO.getEmissionId());
                System.out.println("排放源信息"+emissionSourceDO.toString());
                // 查询排放源的活动系数和单位
                QueryWrapper<EmissionCalculationDO> queryWrapper2 = new QueryWrapper<>();
                queryWrapper2.eq("emission_id", emissionProcessDO.getEmissionId())
                        .eq("process_id", emissionProcessDO.getProcessId())
                        .eq("calculation_id", calculationDO.getId());
                EmissionCalculationDO emissionCalculationDO = emissionCalculationMapper.selectOne(queryWrapper2);
                // 计算排放源排放量
                Double out = emissionSourceDO.getFactorEmissions() * emissionCalculationDO.getNum();
                EmissionSourceDownloadVO emissionSourceDownloadVO = EmissionSourceConvert.INSTANCE.convert(emissionSourceDO);
                // 填入排放源详细信息
                emissionSourceDownloadVO.setNum(emissionCalculationDO.getNum());
                emissionSourceDownloadVO.setUnit(emissionCalculationDO.getUnit());
                emissionSourceDownloadVO.setNum(out);
                emissionSourceDownloadVO.setUnit("kg");
                emissionSourceDownloadVO.setOut(out);
                Double value0 = periodMap.get(periodName);
                Double value1 = periodMap.get("总量");
                periodMap.put(periodName, value0 + out);
                periodMap.put("总量", value1 + out);
                // 将排放源添加到对应的嵌套排放源列表中
                listsEmissionSource.get(index).add(emissionSourceDownloadVO);
            }
        }
        // System.out.println(listsEmissionSource.toString());
        data.put("listsEmissionSource", listsEmissionSource);
        data.put("periodMap", periodMap);
        // 生成word
        byte[] fileBytes = WordUtils.getDocBytes(data, templateName + ".ftl");
        // 上传至文件服务器
        String fileName = "2022年度" + productManagementDO.getName() + "核算";
        String uploadFileName = fileName + "_" + System.currentTimeMillis() + "_" + reportTime + ".docx";
        String fileUrl = fileApi.createFile(uploadFileName, fileBytes);

        System.out.println(uploadFileName);
        // 插入报告下载记录
        ReportDownloadCreateReqVO reportDownloadCreateReqVO = new ReportDownloadCreateReqVO();
        reportDownloadCreateReqVO.setReportId(reqVO.getReportId())
                .setType(reqVO.getType())
                .setFileName(uploadFileName)
                .setReportUrl(fileUrl);
        ReportDownloadDO reportDownload = ReportDownloadConvert.INSTANCE.convert(reportDownloadCreateReqVO);
        reportDownloadMapper.insert(reportDownload);
        Long downLoadId = reportDownload.getId();
        return downLoadId;
    }



    @Override
    public void deleteReportDownload(Long id) {
        // 校验存在
        validateReportDownloadExists(id);
        // 删除
        reportDownloadMapper.deleteById(id);
    }

    private void validateReportDownloadExists(Long id) {
        if (reportDownloadMapper.selectById(id) == null) {
            throw exception(REPORT_DOWNLOAD_NOT_EXISTS);
        }
    }

    @Override
    public ReportDownloadDO getReportDownload(Long id) {
        return reportDownloadMapper.selectById(id);
    }

    @Override
    public String exportReportDownload(@Valid ReportDownloadReqVO exportReqVO) throws IOException, InterruptedException {
        Integer language = exportReqVO.getLanguage();
        ReportDownloadDO reportDownload = reportDownloadMapper.selectById(exportReqVO.getDownloadId());
        // 生成报告
        String fromLang = "zh";
        String toLang;
        String extend = "docx";
        String filePath = reportDownload.getReportUrl();
        String output = "docx";

        // 解析URL，获取文件名
        String[] urlSplit = reportDownload.getReportUrl().split("/");
        String fileName = urlSplit[urlSplit.length - 1];
        System.out.println(fileName);
        System.out.println("!!!!!!!!!!!!!!!!!");

        if (language == 1) {
            return reportDownload.getReportUrl();
        } else if (language == 2) {
            toLang = "en";
            fileName += "（英文版）";
        } else if (language == 3) {
            toLang = "kor";
            fileName += "（韩文版）";
        } else {
            throw exception(REPORT_LANGUAGE_NOT_EXISTS);
        }

        TranslateUtil translate = new TranslateUtil("20230625001723471", "tAUvXp7Op0HpmrDDUONo");
        // 创建报价服务
        String quoteRet = translate.createQuoteJob(fromLang, toLang, extend, fileName, filePath);
        System.out.println("baojia");
        System.out.println(quoteRet);
        JSONObject quoteRetJson = JSON.parseObject(quoteRet);
        String fileId = quoteRetJson.getJSONObject("data").getString("fileId");

        // 查询报价结果
        String queryQuoteRet = translate.queryQuote(fileId);
        System.out.println("jiegou");
        System.out.println(queryQuoteRet);

        // 创建翻译服务
        String transRet = translate.createTransJob(fromLang, toLang, extend, fileName, filePath, output);
        System.out.println(transRet);
        JSONObject transRetJson = JSON.parseObject(transRet);
        String requestId = transRetJson.getJSONObject("data").getString("requestId");

        // 睡眠5秒
        Thread.sleep(10000);

        // 查询翻译结果
        String queryTransRet = translate.queryTrans(requestId);
        System.out.println(queryTransRet);
        JSONObject queryTransRetJson = JSON.parseObject(queryTransRet);
        System.out.println("finally");
        System.out.println(queryTransRetJson);
        return queryTransRetJson.getJSONObject("data").getString("fileSrcUrl");
    }
}

